home *** CD-ROM | disk | FTP | other *** search
- Subject: v19i086: Cnews production release, Part09/19
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: utzoo!henry
- Posting-number: Volume 19, Issue 86
- Archive-name: cnews2/part09
-
- : ---CUT HERE---
- echo 'hfake/timeb.h':
- sed 's/^X//' >'hfake/timeb.h' <<'!'
- X/*
- X * simulation of research unix's <sys/timeb.h> for Uglix.
- X */
- Xstruct timeb {
- X time_t time;
- X unsigned short millitm;
- X short timezone;
- X short dstflag;
- X};
- !
- echo 'hfake/Makefile':
- sed 's/^X//' >'hfake/Makefile' <<'!'
- XI = ../include
- X
- X# beware -- build knows about NEEDED
- XNEEDED = ../include/stdlib.h
- X
- Xall: $(NEEDED)
- X
- X$(I)/stdlib.h: stdlib.h
- X cp stdlib.h $@
- X$(I)/string.h: string.h
- X cp string.h $@
- X$(I)/sys/timeb.h: timeb.h
- X cp timeb.h $@
- X
- Xclean:
- !
- echo 'input/bdecode.c':
- sed 's/^X//' >'input/bdecode.c' <<'!'
- X/*
- X * bdecode [file]
- X */
- X#include <stdio.h>
- X#include "coder.h"
- Xchar *myname, *inputfile = "(stdin)";
- X
- Xmain(argc, argv)
- X char **argv;
- X{
- X register long word;
- X register int c, bcount;
- X register FILE *fin = stdin, *fout = stdout; /* in regs for speed */
- X register char *map, *p;
- X register long nbytes;
- X register int crc;
- X long nbytes2;
- X int w, crc2;
- X char buf[512];
- X extern char *index();
- X
- X myname = argv[0];
- X if (sizeof(word) < 4)
- X fprintf(stderr, "%s: word size too small\n", myname), exit(1);
- X if (argc > 2)
- X fprintf(stderr, "Usage: %s [file]\n", myname), exit(1);
- X if (argc == 2) {
- X if ((fin = fopen(argv[1], "r")) == NULL) {
- X fprintf(stderr, "%s: ", myname);
- X perror(argv[1]);
- X exit(1);
- X }
- X inputfile = argv[1];
- X }
- X /* skip to beginning of encoded data */
- X do {
- X if (fgets(buf, sizeof buf, fin) == NULL)
- X fatal("Missing header");
- X /* trim trailing blanks (sigh) */
- X p = index(buf, '\n');
- X if (p == 0)
- X continue;
- X while (*--p == ' ')
- X ;
- X p[1] = '\n';
- X p[2] = '\0';
- X } while (strcmp(buf, header) != 0);
- X
- X /* define input mapping table */
- X map = buf+1;
- X for (c = 0; c < 256; c++)
- X map[c] = 64; /* illegal */
- X for (c = 0; c < 64; c++)
- X map[ENCODE(c)] = c;
- X map[EOF] = 65; /* special cases */
- X map['/'] = 66;
- X
- X word = 0;
- X bcount = 4;
- X nbytes = 0;
- X crc = 0;
- X#define PUTC(x) { c = (x) & 0xff; CRC(crc, c); putc(c, fout); nbytes++; }
- X for (;;) {
- X c = map[getc(fin)];
- X if ((unsigned)c < 64) {
- X word <<= 6;
- X word |= c;
- X if (--bcount == 0) {
- X PUTC(word >> 16);
- X PUTC(word >> 8);
- X PUTC(word);
- X word = 0;
- X bcount = 4;
- X }
- X continue;
- X }
- X switch (c) {
- X
- X default:
- X /*
- X * Ignore stuff not in the code set.
- X */
- X continue;
- X
- X case 65: /* EOF */
- X fatal("Unexpected EOF");
- X
- X case 66: /* '/' */
- X /* trailer follows: %d%x */
- X c = getc(fin);
- X if (fscanf(fin, "%x", &w) != 1)
- X fatal("Corrupted input (trailer)");
- X switch (c) {
- X case '2': PUTC(w >> 8);
- X case '1': PUTC(w);
- X case '0': break;
- X default: fatal("Corrupted input (trailer)");
- X }
- X /*
- X * Byte count and CRC follow.
- X */
- X if (fscanf(fin, "%ld%x", &nbytes2, &crc2) != 2)
- X fatal("Corrupted input (missing byte count/CRC)");
- X if (nbytes2 != nbytes)
- X fatal("Corrupted input (byte count is wrong)");
- X if (crc2 != (crc & 0xffff))
- X fatal("Corrupted input (CRC mismatch)");
- X exit(0);
- X }
- X }
- X}
- X
- Xfatal(s)
- X char *s;
- X{
- X fprintf(stderr, "%s: %s: %s\n", myname, inputfile, s);
- X exit(2);
- X}
- !
- echo 'input/newsspool.c':
- sed 's/^X//' >'input/newsspool.c' <<'!'
- X/*
- X * newsspool - copy incoming news into incoming directory
- X *
- X * The -i option relies on the parent setting (and exporting) $PATH.
- X *
- X * $Log$
- X */
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <string.h>
- X#include <errno.h>
- X#include "libc.h"
- X#include "news.h"
- X#include "config.h"
- X
- X#ifndef lint
- Xstatic char RCSid[] = "$Header$";
- X#endif
- X
- X#ifndef MAXTRIES
- X#define MAXTRIES 100 /* limit on attempts to make links */
- X#endif
- X
- Xint debug = 0;
- Xchar *progname;
- X
- Xextern void error(), exit();
- X#ifdef UTZOOERR
- Xextern char *mkprogname();
- X#else
- X#define mkprogname(a) (a)
- X#endif
- X
- Xchar buf[BUFSIZ*16]; /* try to get a batch in a few gulps */
- Xint immed = 0; /* try an immediate newsrun? */
- X
- Xvoid process();
- XFILE *outopen();
- Xvoid outclose();
- Xextern time_t time();
- Xchar *outname();
- X
- X/*
- X - main - parse arguments and handle options
- X */
- Xmain(argc, argv)
- Xint argc;
- Xchar *argv[];
- X{
- X int c;
- X int errflg = 0;
- X FILE *in;
- X struct stat statbuf;
- X extern int optind;
- X extern char *optarg;
- X extern FILE *efopen();
- X void process();
- X
- X progname = mkprogname(argv[0]);
- X
- X while ((c = getopt(argc, argv, "id")) != EOF)
- X switch (c) {
- X case 'i': /* try immediate newsrun */
- X immed++;
- X break;
- X case 'd': /* Debugging. */
- X debug++;
- X setbuf(stderr, (char *)NULL);
- X break;
- X case '?':
- X default:
- X errflg++;
- X break;
- X }
- X if (errflg) {
- X fprintf(stderr, "usage: %s [file] ...\n", progname);
- X exit(2);
- X }
- X
- X /* probe to get unprivileged() called if necessary */
- X (void) ctlfile((char *)NULL);
- X
- X /* mktemp() uses access(2) [ARGH!] so minimize chances of trouble */
- X (void) setgid(getegid());
- X (void) setuid(geteuid());
- X
- X (void) umask(newsumask());
- X
- X if (optind >= argc)
- X process(stdin, "stdin");
- X else
- X for (; optind < argc; optind++)
- X if (STREQ(argv[optind], "-"))
- X process(stdin, "-");
- X else {
- X in = efopen(argv[optind], "r");
- X if (fstat(fileno(in), &statbuf) < 0)
- X error("can't fstat `%s'", argv[optind]);
- X if ((statbuf.st_mode & S_IFMT) == S_IFDIR)
- X error("`%s' is directory!", argv[optind]);
- X process(in, argv[optind]);
- X (void) fclose(in);
- X }
- X
- X if (immed) {
- X /* execlp because shell files may not be directly execable */
- X execlp(binfile("input/newsrun"), "newsrun", (char *)NULL);
- X error("attempt to run newsrun failed!", "");
- X }
- X exit(0);
- X}
- X
- X/*
- X * process - process input file
- X */
- X/* ARGSUSED */
- Xvoid
- Xprocess(in, inname)
- XFILE *in;
- Xchar *inname;
- X{
- X register int count;
- X register int firstblock;
- X FILE *out;
- X register char *p;
- X register int n;
- X char *name;
- X
- X name = outname();
- X out = outopen(name);
- X
- X /* do the copying */
- X firstblock = 1;
- X while ((count = fread(buf, sizeof(char), sizeof(buf), in)) > 0) {
- X if (firstblock) {
- X n = cunskip(buf, count);
- X p = buf + n;
- X count -= n;
- X firstblock = 0;
- X } else
- X p = buf;
- X n = fwrite(p, sizeof(char), count, out);
- X if (n != count)
- X error("write error in output to `%s'", name);
- X }
- X
- X outclose(out, name);
- X}
- X
- X/*
- X - outname - construct name for the temporary output file
- X */
- Xchar *
- Xoutname()
- X{
- X register char *p;
- X
- X p = strsave(fullartfile("in.coming/nspool.XXXXXX"));
- X mktemp(p);
- X return(p);
- X}
- X
- X/*
- X - outopen - acquire an output file
- X */
- XFILE *
- Xoutopen(name)
- Xchar *name;
- X{
- X FILE *f;
- X
- X f = fopen(name, "w");
- X if (f == NULL)
- X error("unable to create temporary `%s'", name);
- X if (debug)
- X fprintf(stderr, "output into %s\n", name);
- X
- X return(f);
- X}
- X
- X/*
- X - outclose - close output file, moving it to the right place
- X *
- X * Names are based on the current time in hopes of keeping input in order.
- X */
- Xvoid
- Xoutclose(f, tmpname)
- XFILE *f;
- Xchar *tmpname;
- X{
- X register char *p;
- X register char *name;
- X register int ntries;
- X time_t now;
- X extern int errno;
- X
- X if (fclose(f) == EOF)
- X error("fclose error on file `%s'", tmpname);
- X
- X p = fullartfile("in.coming/");
- X name = emalloc(strlen(p) + 20); /* plenty for a number */
- X (void) strcpy(name, p);
- X p = name + strlen(name);
- X
- X ntries = 0;
- X for (;;) {
- X now = time((time_t *)NULL);
- X sprintf(p, "%ld", now);
- X if (debug)
- X fprintf(stderr, "trying renaming to %s\n", name);
- X if (link(tmpname, name) >= 0)
- X break; /* NOTE BREAK OUT */
- X if (errno != EEXIST) /* something strange is wrong */
- X error("unable to link `%s'", tmpname);
- X errno = 0;
- X if (ntries > MAXTRIES) /* sanity check */
- X error("too many attempts to link `%s'", tmpname);
- X if (debug)
- X fprintf(stderr, "failed\n");
- X sleep(2); /* avoid rumored race in 1-sec sleep */
- X ntries++;
- X }
- X
- X if (debug)
- X fprintf(stderr, "succeeded\n");
- X (void) unlink(tmpname);
- X}
- X
- X/*
- X - cunskip - inspect block for silly #! cunbatch headers
- X */
- Xint /* number of chars at start to skip */
- Xcunskip(bufp, count)
- Xchar *bufp;
- Xint count;
- X{
- X static char goop[] = "cunbatch";
- X# define GOOPLEN (sizeof(goop)-1) /* strlen(goop) */
- X static char goop2[] = "c7unbatch";
- X# define GOOP2LEN (sizeof(goop2)-1) /* strlen(goop2) */
- X register char *p;
- X register int nleft;
- X
- X nleft = count;
- X p = bufp;
- X
- X if (nleft < 2) /* no room for a header */
- X return(0);
- X if (*p++ != '#' || *p++ != '!') /* doesn't start with #! */
- X return(0);
- X nleft -= 2;
- X
- X /* skip space */
- X while (nleft > 0 && (*p == ' ' || *p == '\t')) {
- X p++;
- X nleft--;
- X }
- X
- X /* recognize headers (the +1s ensure room for the newline) */
- X if (nleft >= GOOPLEN+1 && STREQN(p, goop, GOOPLEN)) {
- X p += GOOPLEN;
- X nleft -= GOOPLEN;
- X } else if (nleft >= GOOP2LEN+1 && STREQN(p, goop2, GOOP2LEN)) {
- X p += GOOP2LEN;
- X nleft -= GOOP2LEN;
- X } else /* no header */
- X return(0);
- X
- X /* skip more space */
- X while (nleft > 0 && (*p == ' ' || *p == '\t')) {
- X p++;
- X nleft--;
- X }
- X
- X if (nleft == 0 || *p++ != '\n') /* didn't end properly */
- X return(0);
- X
- X return(p - bufp);
- X}
- X
- X/*
- X - unprivileged - drop setuidness if configuration is overridden
- X */
- Xvoid
- Xunprivileged()
- X{
- X setgid(getgid());
- X setuid(getuid());
- X}
- !
- echo 'input/Makefile':
- sed 's/^X//' >'input/Makefile' <<'!'
- X# You get your choice of rnews.immed or rnews.batch; rnews.immed tries
- X# to start processing immediately, while rnews.batch waits for somebody
- X# else (cron) to do it. Running rnews.immed might, perhaps, be reasonable
- X# if your news load is light and you are wildly impatient about processing
- X# incoming news. Otherwise, leave this alone.
- XRNEWS = rnews.batch
- X
- XDEFINES =
- XCOPTS = -O
- XCFLAGS = $(COPTS) $(DEFINES) -I../include
- XLINTFLAGS = $(DEFINES) -I../include -ha
- XLDFLAGS = $(CFLAGS)
- XLIBS= ../libcnews.a
- XBATCH = ../batch
- XTHEMBIN = newsrun newsrunning c7decode bdecode recenews recpnews rnews
- XTHEM = newsspool $(THEMBIN)
- XRBIN = /bin
- X# =()<NEWSARTS = @<NEWSARTS>@>()=
- XNEWSARTS = /usr/spool/news
- X# =()<NEWSBIN = @<NEWSBIN>@>()=
- XNEWSBIN = /usr/lib/newsbin
- X# workaround for System V make bug
- XSHELL = /bin/sh
- XDTR = README Makefile newsrun newsrunning newsspool.c c7decode.c rnews.batch \
- X rnews.8 bdecode.c recenews recpnews
- X
- Xall: $(THEM) rnews
- X
- Xbininstall: all
- X chmod +x $(THEM) rnews
- X -if test ! -d $(NEWSBIN)/input ; then mkdir $(NEWSBIN)/input ; fi
- X rm -f $(NEWSBIN)/input/newsspool
- X cp $(THEM) $(NEWSBIN)/input
- X cp rnews $(RBIN)/rnews
- X cp rnews $(RBIN)/cunbatch
- X : "and newsspool needs to be made setuid-news"
- X
- Xnewsinstall:
- X : nothing
- X
- Xnewsspool: newsspool.o $(LIBS)
- X $(CC) $(LDFLAGS) newsspool.o $(LIBS) -o $@
- X
- Xc7decode: c7decode.o $(LIBS)
- X $(CC) $(LDFLAGS) c7decode.o $(LIBS) -o $@
- X
- Xbdecode: bdecode.o $(BATCH)/crctab.o $(LIBS)
- X $(CC) $(LDFLAGS) bdecode.o $(BATCH)/crctab.o $(LIBS) -o $@
- X
- X$(BATCH)/crctab.o: $(BATCH)/crctab.c
- X ( cd $(BATCH) ; make crctab.o )
- X
- Xbdecode.o: bdecode.c $(BATCH)/coder.h
- X $(CC) -c -I$(BATCH) $(CFLAGS) bdecode.c
- X
- Xlint: newsspool.c
- X lint $(LINTFLAGS) newsspool.c 2>&1 | tee lint
- X
- Xtest.1:
- X echo '#! rnews' >$@
- X echo 'here is a phony first batch' >>$@
- X
- Xtest.2:
- X echo '#! cunbatch' >$@
- X echo '#! rnews' >>$@
- X echo 'here is a phony second batch' >>$@
- X
- Xtest.3p:
- X echo '#! rnews' >$@
- X echo 'here is a phony third batch' >>$@
- X
- Xtest.3: test.3c
- X ( echo '#! cunbatch' ; cat test.3c ) >$@
- X
- Xtest.3c: test.3p
- X : compress tends to return silly exit status for tiny inputs
- X -compress -b12 <test.3p >$@
- X
- Xtest.out:
- X echo '#! rnews' >$@
- X echo 'here is a phony first batch' >>$@
- X echo '#! rnews' >>$@
- X echo 'here is a phony second batch' >>$@
- X echo '#! rnews' >>$@
- X echo 'here is a phony third batch' >>$@
- X
- Xrnews.immed: rnews.batch
- X sed '/qqq/s/newsspool/& -i/' rnews.batch >$@
- X
- Xrnews: rnews.batch rnews.immed
- X cp $(RNEWS) rnews
- X chmod +x rnews
- X
- Xsetup: all
- X chmod +x rnews.batch rnews.immed
- X rm -rf bin
- X mkdir bin
- X cp $(THEM) bin
- X mkdir bin/input
- X cp newsrun bin/input
- X rm -f tmp.1
- X here=`pwd` ; echo "cat >>$$here/tmp.1" >bin/relaynews
- X echo "echo 1" >bin/spacefor
- X echo 'ln $$*' >bin/newslock
- X echo 'echo 10' >bin/sizeof
- X chmod +x bin/* bin/input/*
- X rm -rf in.coming
- X mkdir in.coming
- X
- Xr: all test.1 test.2 test.3 test.3c test.out setup
- X chmod +x $(THEM)
- X NEWSARTS=`pwd` NEWSCTL=`pwd` ./rnews.batch <test.1
- X cmp in.coming/* test.1
- X NEWSARTS=`pwd` NEWSCTL=`pwd` ./rnews.batch <test.2
- X sed 1d test.2 >tmp.2
- X cmp `ls -t in.coming | sed -n '1s;^;in.coming/;p'` tmp.2
- X rm tmp.2
- X NEWSARTS=`pwd` NEWSCTL=`pwd` ./rnews.batch <test.3
- X cmp `ls -t in.coming | sed -n '1s;^;in.coming/;p'` test.3c
- X NEWSARTS=`pwd` NEWSCTL=`pwd` ./newsrunning off
- X test -r in.coming/stop
- X NEWSARTS=`pwd` NEWSCTL=`pwd` ./newsrunning on
- X test ! -r in.coming/stop
- X mkdir in.coming/bad
- X NEWSARTS=`pwd` NEWSCTL=`pwd` ./newsrun
- X cmp tmp.1 test.out
- X test " `echo in.coming/*`" = ' in.coming/bad'
- X rm tmp.1
- X NEWSARTS=`pwd` NEWSCTL=`pwd` ./rnews.batch <test.1
- X NEWSARTS=`pwd` NEWSCTL=`pwd` ./rnews.batch <test.2
- X NEWSARTS=`pwd` NEWSCTL=`pwd` NEWSBIN=`pwd`/bin ./rnews.immed <test.3
- X cmp tmp.1 test.out
- X test " `echo in.coming/*`" = ' in.coming/bad'
- X rm tmp.1
- X rm -r bin in.coming
- X
- Xclean:
- X rm -f *.o newsspool c7decode tmp.? test.* dtr lint rnews rnews.immed
- X rm -f bdecode
- X rm -rf in.coming bin
- X
- Xdtr: $(DTR)
- X makedtr $(DTR) >dtr
- !
- echo 'input/README':
- sed 's/^X//' >'input/README' <<'!'
- XThis is the input processing, which starts at rnews (aka cunbatch). It
- Xinvokes newsspool, which actually puts the stuff where it belongs (peeling
- Xoff the silly and unnecessary "#! cunbatch" header, if any, as it goes).
- X
- XNewsrun should be run regularly; it unspools the stuff and feeds it into
- Xthe relay subsystem for processing. Newsrunning can be used to turn this
- Xfunction on and off if you want to avoid news processing during busy hours.
- X
- XUsing rnews.immed instead of rnews.batch as rnews will arrange for newsrun
- Xto be run after each newsspool -- this is expensive but cuts down latency.
- XIf you've got a fast machine and a light newsfeed and totally lack patience,
- Xlike Geoff :-), this might be a good idea; otherwise, no.
- X
- X"make r" builds everything and runs a full regression test on most everything.
- !
- echo 'input/recenews':
- sed 's/^X//' >'input/recenews' <<'!'
- X#! /bin/sh
- X# News reception via mail, bencoded format.
- X
- X# =()<. ${NEWSCONFIG-@<NEWSCONFIG>@}>()=
- X. ${NEWSCONFIG-/usr/lib/news/bin/config}
- X
- XPATH=$NEWSCTL/bin:$NEWSBIN/input:$NEWSBIN:$NEWSPATH ; export PATH
- Xumask $NEWSUMASK
- X
- Xbdecode | rnews
- !
- echo 'input/newsrun':
- sed 's/^X//' >'input/newsrun' <<'!'
- X#! /bin/sh
- X# Process spooled news.
- X
- X# =()<. ${NEWSCONFIG-@<NEWSCONFIG>@}>()=
- X. ${NEWSCONFIG-/usr/lib/news/bin/config}
- X
- XPATH=$NEWSCTL/bin:$NEWSBIN/input:$NEWSBIN/relay:$NEWSBIN:$NEWSPATH ; export PATH
- Xumask $NEWSUMASK
- X
- Xhere="$NEWSARTS/in.coming"
- Xcd $here
- X
- X# First, is it worth trying at all?
- Xif test -r stop
- Xthen
- X exit 0
- Xfi
- X
- X# Lock against others running.
- Xlock="$NEWSCTL/LOCKinput"
- Xltemp="$NEWSCTL/L.$$"
- Xecho $$ >$ltemp
- Xtrap "rm -f $ltemp ; exit 0" 0 1 2 15
- Xif newslock $ltemp $lock
- Xthen
- X trap "rm -f $ltemp $lock ; exit 0" 0 1 2 15
- Xelse
- X exit 0
- Xfi
- X
- X# Sort out where we are.
- Xif test -r $NEWSCTL/server
- Xthen
- X me="`hostname`"
- X server=`cat $NEWSCTL/server`
- Xelse
- X me=me # don't need actual name
- X server="$me" # no server file --> we're it
- Xfi
- X
- X# Master loop.
- Xwhile : # "while true", but : is faster
- Xdo
- X # Find some work.
- X them=`ls | sed '/[^0-9]/d;50q'`
- X if test " $them" = " "
- X then
- X break # NOTE BREAK OUT
- X fi
- X
- X # Check space. It is *probably* better to stop processing
- X # when things get too full. (This test is actually a bit
- X # inaccurate since the batches may be compressed, but it's
- X # good enough to catch major space problems.)
- X allsize=`sizeof $them`
- X if test " `spacefor $allsize articles`" -gt 1 # lots of room
- X then
- X muchroom=y
- X else
- X muchroom=
- X fi
- X
- X # Do it.
- X rmlist=
- X for f in $them
- X do
- X # Check for request to stop.
- X if test -r stop
- X then
- X rm -f $rmlist
- X exit 0
- X fi
- X
- X # Check for empty.
- X if test ! -s $f
- X then
- X rm -f $f
- X continue # NOTE CONTINUE
- X fi
- X
- X # Space check, if we're close.
- X if test " $muchroom" != " y"
- X then
- X batchsize=`sizeof $f`
- X if test " `spacefor $batchsize articles`" -le 0
- X then
- X rm -f $rmlist
- X exit 0
- X fi
- X fi
- X
- X # Decompress if necessary. People who get lots of
- X # uncompressed batches and never use c7 encoding might
- X # want to remove the c7decode attempt to speed things up.
- X text=nruntmp.$$
- X if compress -d <$f >$text 2>/dev/null
- X then
- X rmlist="$rmlist $f $text"
- X elif c7decode <$f 2>/dev/null | compress -d >$text 2>/dev/null
- X then
- X rmlist="$rmlist $f $text"
- X else
- X rm -f $text
- X text=$f
- X rmlist="$rmlist $f"
- X fi
- X
- X # Do it. -r redirects stdout and stderr into logs. -n makes
- X # history entries for refused articles; this is right for
- X # NNTP-feed sites and doesn't hurt uucp-feed sites unless
- X # they refuse a good fraction of what they get.
- X if test " $server" = " $me" # if local
- X then
- X relaynews -r -n <$text
- X else
- X # N.B.: rsh always returns exit status 0!
- X rsh $server "PATH=$PATH relaynews -r -n" <$text
- X fi
- X st=$?
- X if test $st -ne 0
- X then
- X # trouble
- X if test ! -d bad
- X then
- X mkdir bad
- X fi
- X bad=bad/$f
- X
- X if test -s bad/limit
- X then
- X limit=`sed 1q bad/limit`
- X else
- X limit=50
- X fi
- X nfiles=`ls bad | wc | awk '{print $1}'`
- X if test " $nfiles" -lt " $limit"
- X then
- X mv $f $bad # Not $text, save the ORIGINAL!
- X fi
- X echo "$server $consumer \`$bad' failed, status $st" |
- X mail "$NEWSMASTER"
- X fi
- X
- X done
- X rm -f $rmlist
- Xdone
- X
- Xexit 0
- !
- echo 'input/newsrunning':
- sed 's/^X//' >'input/newsrunning' <<'!'
- X#! /bin/sh
- X# newsrunning - turn news processing on and off
- X
- X# =()<. ${NEWSCONFIG-@<NEWSCONFIG>@}>()=
- X. ${NEWSCONFIG-/usr/lib/news/bin/config}
- X
- XPATH=$NEWSCTL/bin:$NEWSBIN/input:$NEWSBIN:$NEWSPATH ; export PATH
- Xumask $NEWSUMASK
- X
- Xstop=$NEWSARTS/in.coming/stop
- X
- Xcase "$1"
- Xin
- X on)
- X rm -f $stop
- X ;;
- X
- X off)
- X if test ! -r $stop # don't update already-existing file
- X then
- X >$stop
- X fi
- X ;;
- X
- X *)
- X echo "Usage: $0 on/off" >&2
- X exit 2
- X ;;
- Xesac
- X
- Xexit 0
- !
- echo 'input/c7decode.c':
- sed 's/^X//' >'input/c7decode.c' <<'!'
- X#include <stdio.h>
- X
- X/*
- X * This program is the inverse of encode
- X *
- X * It collects runs of 12 characters, combines pairs of those
- X * to form 6 13 bit numbers, extracts the top bit of each of
- X * those to make a 13th 6 bit character, and splits each of
- X * the remaining 6 12 bit numbers to form 12 6 bit ones.
- X *
- X * The strings of 6 bit numbers are collected into groups of
- X * 4 and converted into 3 8 bit characters.
- X *
- X * Now all that would be trivial, if we didn't need to worry
- X * about ending all this correctly. About 1/2 of the following
- X * program wouldn't be here if the ending didn't matter....
- X */
- X
- X/*
- X * the following pair of characters can never occur as a pair
- X * in legal input (since (90 * 91 + 90) > 2^13) - they are
- X * noticed at the beginning of a 12 char block, and serve to
- X * indicate that this block is the terminator. The character
- X * immediately following is the (expanded) terminator length.
- X */
- X#define ENDMARK1 ((90*91 + 90) / 91)
- X#define ENDMARK2 ((90*91 + 90) % 91)
- X
- Xint errcnt = 0;
- X
- Xmain()
- X{
- X register c;
- X register char *p;
- X register i;
- X register first = 1;
- X register cnt = 0;
- X char b12[12];
- X char c12[12];
- X
- X p = b12;
- X i = 12;
- X
- X while ((c = getchar()) != EOF) {
- X if (c < ' ' || c >= (' ' + 91)) {
- X if (errcnt++ == 0)
- X fprintf(stderr, "c7decode: Bad data\n");
- X continue;
- X }
- X if (i == 10 && p[-1] == ENDMARK1 && p[-2] == ENDMARK2) {
- X cnt = c - ' ';
- X i = 12;
- X p -= 2;
- X continue;
- X }
- X *p++ = c - ' ';
- X if (--i == 0) {
- X if (p == &b12[12]) {
- X if (!first)
- X pack12(c12, 12, 0);
- X else
- X first = 0;
- X p = c12;
- X } else {
- X pack12(b12, 12, 0);
- X p = b12;
- X }
- X i = 12;
- X }
- X }
- X
- X if (p >= &b12[0] && p < &b12[12]) {
- X if (!first)
- X pack12(c12, 12, i == 12 ? cnt : 0);
- X } else
- X pack12(b12, 12, i == 12 ? cnt : 0);
- X
- X if (i != 12) {
- X if (p >= &b12[0] && p < &b12[12])
- X pack12(b12, 12-i, cnt);
- X else
- X pack12(c12, 12-i, cnt);
- X }
- X
- X exit((errcnt > 0) ? 1 : 0);
- X}
- X
- Xstatic char b4[4];
- Xstatic int cnt = 0;
- X
- Xpack12(p, n, last)
- X register char *p;
- X register n;
- X int last;
- X{
- X register i;
- X register char *q;
- X char b13[13];
- X
- X {
- X register c;
- X register c13;
- X
- X q = b13;
- X c13 = 0;
- X
- X for (i = 0; i < n; i += 2) {
- X c = *p++ * 91;
- X c += *p++;
- X c13 <<= 1;
- X if (c & (1 << 12))
- X c13 |= 1;
- X *q++ = (c >> 6) & 0x3f;
- X *q++ = c & 0x3f;
- X }
- X *q++ = c13;
- X if (last)
- X q = &b13[last];
- X }
- X
- X p = b13;
- X n = q - p;
- X i = cnt;
- X q = &b4[cnt];
- X
- X while (--n > 0) {
- X *q++ = *p++;
- X if (++i == 4) {
- X char b3[3];
- X register char *b = b4;
- X
- X /* inline expansion of pack6bit, to save calls ... */
- X
- X q = b3;
- X *q++ = (b[0] << 2) | ((b[1] >> 4) & 0x3);
- X *q++ = (b[1] << 4) | ((b[2] >> 2) & 0xf);
- X *q = (b[2] << 6) | (b[3] & 0x3f);
- X
- X q = b3;
- X while (--i > 0)
- X putchar(*q++);
- X
- X q = b4;
- X }
- X }
- X
- X *q++ = *p++; /* the last octet */
- X ++i;
- X
- X if (last || i == 4) {
- X pack6bit(b4, i, last);
- X i = 0;
- X }
- X
- X cnt = i;
- X}
- X
- Xpack6bit(p, n, last)
- X register char *p;
- X register int n;
- X int last;
- X{
- X register char *q;
- X register i = 3;
- X char b3[3];
- X
- X if (last) {
- X i = p[n-1];
- X if (i >= 3) {
- X fprintf(stderr, "c7decode: Badly encoded file\n");
- X errcnt++;
- X i = 3; /* do the best we can */
- X }
- X }
- X
- X q = b3;
- X *q++ = (p[0] << 2) | ((p[1] >> 4) & 0x3);
- X *q++ = (p[1] << 4) | ((p[2] >> 2) & 0xf);
- X *q = (p[2] << 6) | (p[3] & 0x3f);
- X
- X q = b3;
- X
- X while (--i >= 0)
- X putchar(*q++);
- X}
- !
- echo 'input/rnews.batch':
- sed 's/^X//' >'input/rnews.batch' <<'!'
- X#! /bin/sh
- X# Incoming-news spooling.
- X# We ignore arguments -- it looks tempting to put "$*" after cat and
- X# newsspool, but there are security problems.
- X
- X# =()<. ${NEWSCONFIG-@<NEWSCONFIG>@}>()=
- X. ${NEWSCONFIG-/usr/lib/news/bin/config}
- X
- XPATH=$NEWSCTL/bin:$NEWSBIN/input:$NEWSBIN:$NEWSPATH ; export PATH
- Xumask $NEWSUMASK
- X
- X# check space, assuming a pretty large batch (no cheap way to find real size)
- Xcounter=1
- Xwhile test " `spacefor 250000 incoming`" -le 0
- Xdo
- X sleep 300
- X if test " $counter" -gt 1111 # four tries is plenty
- X then
- X # oh no! -- nothing we can do, really...
- X cat >/dev/null
- X echo incoming news discarded due to space shortage |
- X mail "$NEWSMASTER"
- X exit 1
- X fi
- X counter="1$counter"
- Xdone
- X
- Xif newsspool >/tmp/ngripe.$$ 2>&1 # qqq (marker for Makefile)
- Xthen
- X rm -f /tmp/ngripe.$$
- X exit 0
- Xelse
- X # there really isn't any way to save the data if newsspool fails,
- X # not without causing other problems
- X (
- X echo newsspool failed!!!
- X cat /tmp/ngripe.$$
- X ) | mail "$NEWSMASTER"
- X rm -f /tmp/ngripe.$$
- X exit 1
- Xfi
- !
- echo 'input/recpnews':
- sed 's/^X//' >'input/recpnews' <<'!'
- X#! /bin/sh
- X# News reception via mail, protected format (inferior to bencode).
- X
- X# =()<. ${NEWSCONFIG-@<NEWSCONFIG>@}>()=
- X. ${NEWSCONFIG-/usr/lib/news/bin/config}
- X
- XPATH=$NEWSCTL/bin:$NEWSBIN/input:$NEWSBIN:$NEWSPATH ; export PATH
- Xumask $NEWSUMASK
- X
- Xsed -n '1,/^$/d
- Xs/^N//p' | rnews
- !
- echo 'libbig/active.fast.c':
- sed 's/^X//' >'libbig/active.fast.c' <<'!'
- X/*
- X * active file access functions (big, fast, in-memory version)
- X */
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include "libc.h"
- X#include "news.h"
- X#include "config.h"
- X#include "active.h"
- X
- X/* private */
- Xstatic char *active = NULL; /* cache: points at entire active file */
- Xstatic int actsize; /* bytes in active: type int fixed by fread */
- Xstatic char **actlnps; /* point at lines in active file */
- Xstatic unsigned actlines; /* lines in actlnps actually used */
- X
- X/* imports from active.c */
- Xextern char actrelnm[];
- X
- X/* forwards */
- XFORWARD statust actmkindx();
- X
- Xstatust
- Xactfload(fp)
- XFILE *fp;
- X{
- X statust status = ST_OKAY;
- X
- X if (fp != NULL && active == NULL) {
- X struct stat sb;
- X
- X errno = 0;
- X if (fstat(fileno(fp), &sb) < 0)
- X warning("can't fstat `%s'", ctlfile(actrelnm));
- X else if (actsize = sb.st_size, /* squeeze into an int */
- X (unsigned)actsize != sb.st_size)
- X warning("`%s' won't fit into memory", ctlfile(actrelnm));
- X else if ((active = malloc((unsigned)actsize+1)) == NULL)
- X warning("can't allocate memory for `%s'",
- X ctlfile(actrelnm));
- X else {
- X rewind(fp);
- X /*
- X * If we read with fgetms, we might be able to avoid
- X * calling linescan().
- X */
- X if (fread(active, 1, actsize, fp) != actsize) {
- X warning("error reading `%s'", ctlfile(actrelnm));
- X status |= ST_DROPPED;
- X } else
- X status |= actmkindx();
- X }
- X if (active == NULL)
- X status |= ST_DROPPED; /* give up! */
- X if (status != ST_OKAY) {
- X nnfree(&active);
- X nnafree(&actlnps);
- X }
- X }
- X return status;
- X}
- X
- Xstatic statust
- Xactmkindx() /* build actlnps index for active */
- X{
- X register statust status = ST_OKAY;
- X unsigned lnpsz;
- X int maxlines;
- X
- X active[actsize] = '\0'; /* make a proper string */
- X /* +1 for a possible partial line +1 for a dummy to check overflow */
- X maxlines = charcount(active, '\n') + 2;
- X lnpsz = sizeof(char *) * (long) maxlines;
- X if (lnpsz != sizeof(char *) * (long)maxlines ||
- X (actlnps = (char **)malloc(lnpsz)) == NULL) {
- X warning("`%s' index won't fit in memory", ctlfile(actrelnm));
- X status |= ST_DROPPED;
- X } else {
- X actlnps[maxlines - 2] = ""; /* in case no partial line */
- X actlnps[maxlines - 1] = ""; /* end sentinel */
- X actlines = linescan(active, actlnps, maxlines);
- X if (actlines >= maxlines) {
- X (void) fprintf(stderr,
- X "%s: too many newsgroups in `%s' (can't happen)\n",
- X progname, ctlfile(actrelnm));
- X status |= ST_DROPPED;
- X }
- X }
- X return status;
- X}
- X
- X/*
- X * Store in lnarray the addresses of the starts of lines in s.
- X * Return the number of lines found; if greater than nent,
- X * store only nent and return nent.
- X * Thus lnarray should be one bigger than needed to detect overflow.
- X */
- Xint
- Xlinescan(s, lnarray, nent)
- Xchar *s;
- Xchar **lnarray;
- Xregister int nent;
- X{
- X register char **lnarrp = lnarray;
- X register int i = 0;
- X register char *nlp = s;
- X
- X if (i < nent)
- X *lnarrp++ = nlp;
- X while (++i < nent && (nlp = index(nlp, '\n')) != NULL && *++nlp != '\0')
- X *lnarrp++ = nlp;
- X return i; /* number of addrs stored */
- X}
- X
- Xstatust
- Xactfsync(fp) /* write to disk, fp is open */
- XFILE *fp;
- X{
- X statust status = ST_OKAY;
- X
- X rewind(fp);
- X if (active != NULL) {
- X if (fwrite(active, actsize, 1, fp) != 1)
- X status |= ST_DROPPED; /* serious loss */
- X nnfree(&active);
- X nnafree(&actlnps);
- X }
- X return status;
- X}
- X
- X/* ARGSUSED fp */
- Xchar *
- Xactfind(fp, ng, nglen)
- XFILE *fp;
- Xregister char *ng;
- Xregister int nglen;
- X{
- X register char *pos;
- X register unsigned line = 0;
- X
- X while (pos = actlnps[line], line++ < actlines && pos[0] != '\0')
- X if (STREQN(pos, ng, nglen) && pos[nglen] == ' ')
- X return pos;
- X return NULL;
- X}
- X
- X/* ARGSUSED */
- Xstatust
- Xactfwrnum(fp, pos)
- XFILE *fp;
- Xchar *pos;
- X{
- X return ST_OKAY;
- X}
- !
- echo 'libbig/sys.fast.c':
- sed 's/^X//' >'libbig/sys.fast.c' <<'!'
- X/*
- X * news sys file reading functions (fast, big, in-memory version)
- X */
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include "news.h"
- X#include "system.h"
- X
- X/* imports */
- Xextern struct system *currsys, *firstsys;
- X
- X/* exports */
- Xboolean justone = NO;
- X
- X/* private */
- Xstatic struct system *thissys = NULL;
- X
- X/* ARGSUSED */
- Xvoid
- Xrewsys(fp)
- XFILE *fp;
- X{
- X currsys = firstsys;
- X}
- X
- Xstruct system *
- Xmysysincache() /* optimisation */
- X{
- X return thissys;
- X}
- X
- Xvoid
- Xremmysys(sys) /* remember this system */
- Xstruct system *sys;
- X{
- X thissys = sys;
- X}
- X
- Xvoid
- Xfreecurrsys()
- X{
- X /* never free sys entries */
- X}
- !
- echo 'libbig/Makefile':
- sed 's/^X//' >'libbig/Makefile' <<'!'
- X# libbig makefile
- XINCLUDE=../include
- XDEFINES=-I$(INCLUDE) -I../relay
- XCOPTS= -O # -g -p -pg
- XCFLAGS= $(COPTS) $(DEFINES)
- XLINTFLAGS=-hau $(DEFINES)
- XLIB=libbig.a
- X# RANLIB is ranlib on non-USG systems, echo on USG systems
- XRANLIB=ranlib
- X#RANLIB=:
- XSRCS=active.fast.c sys.fast.c
- XOBJS=active.fast.o sys.fast.o
- X# workaround for System V make bug
- XSHELL = /bin/sh
- X
- Xu: $(OBJS)
- X ar ruv ../libcnews.a $(OBJS)
- X
- Xall: $(OBJS)
- X
- X$(LIB): $(SRCS)
- X $(CC) $(CFLAGS) -c $?
- X ar rv $@ *.o
- X rm *.o
- X $(RANLIB) $@
- X
- Xlint:
- X lint $(LINTFLAGS) $(SRCS)
- X
- Xclean:
- X rm -f *.o
- !
- echo 'libbsd42/clsexec.c':
- sed 's/^X//' >'libbsd42/clsexec.c' <<'!'
- X/*
- X * set close on exec (on Berklix)
- X */
- X
- X#include <stdio.h>
- X#include <sgtty.h>
- X
- Xvoid
- Xfclsexec(fp)
- XFILE *fp;
- X{
- X (void) ioctl(fileno(fp), FIOCLEX, (char *)NULL);
- X}
- !
- echo 'libbsd42/getcwd.c':
- sed 's/^X//' >'libbsd42/getcwd.c' <<'!'
- X/*
- X * SystemV getcwd simulation on 4.2BSD
- X */
- X
- X#include <stdio.h>
- X#include <sys/param.h>
- X
- X/* imports from libc */
- Xextern char *getwd();
- Xextern char *strncpy();
- X
- Xchar *
- Xgetcwd(path, size)
- Xregister char *path;
- Xint size;
- X{
- X if (size >= MAXPATHLEN)
- X return getwd(path);
- X else {
- X char wd[MAXPATHLEN];
- X
- X if (getwd(wd) == 0)
- X return 0;
- X else {
- X (void) strncpy(path, wd, size-1);
- X path[size-1] = '\0';
- X return path;
- X }
- X }
- X}
- !
- echo 'libbsd42/fopenexcl.c':
- sed 's/^X//' >'libbsd42/fopenexcl.c' <<'!'
- X/*
- X * fopenexcl(name) - fopen(name, "w") with error if name exists (Berklix)
- X */
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <sys/file.h> /* 4.2's O_EXCL defn */
- X
- XFILE *
- Xfopenexcl(name)
- Xregister char *name;
- X{
- X /* This is the cheaper way. */
- X register int fd = open(name, O_WRONLY|O_CREAT|O_EXCL, 0666);
- X
- X if (fd < 0)
- X return NULL; /* name existed or couldn't be made */
- X else
- X return fdopen(fd, "w");
- X}
- !
- echo 'libbsd42/Makefile':
- sed 's/^X//' >'libbsd42/Makefile' <<'!'
- X# C news libbsd42 makefile
- XINCLUDE = ../include
- XDEFINES=-I$(INCLUDE)
- XCOPTS=-O # -g -p
- XCFLAGS=$(COPTS) $(DEFINES)
- XLINTFLAGS=-hau $(DEFINES)
- X# workaround for System V make bug
- XSHELL = /bin/sh
- X
- XSRCS = clsexec.c fopenexcl.c getcwd.c
- XOBJS = clsexec.o fopenexcl.o getcwd.o
- X
- X# RANLIB is ranlib on non-USG systems, echo on USG systems
- XRANLIB=ranlib
- X
- Xu: $(OBJS)
- X ar ruv ../libcnews.a $(OBJS)
- X
- Xall: $(OBJS)
- X
- Xlibbsd42.a: $(SRCS)
- X $(CC) $(CFLAGS) -c $?
- X ar ru $@ *.o
- X rm *.o
- X $(RANLIB) $@
- Xlint:
- X lint $(LINTFLAGS) $(SRCS)
- X
- Xclean:
- X rm -f *.o
- !
- echo 'libc/Makefile':
- sed 's/^X//' >'libc/Makefile' <<'!'
- X# C news local libc makefile - added by Ian Darwin
- XINCLUDE=../include
- XDEFINES=-I$(INCLUDE)
- XCOPTS=-O # -g -p
- XCFLAGS=$(COPTS) $(DEFINES)
- XLINTFLAGS=-hau $(DEFINES)
- X# workaround for System V make bug
- XSHELL = /bin/sh
- X
- XSRCS=closeall.c efopen.c error.c fgetmfs.c \
- X nfclose.c \
- X standard.c stdfdopen.c warning.c emalloc.c
- XOBJS = closeall.o efopen.o error.o fgetmfs.o getdate.o nfclose.o \
- X standard.o stdfdopen.o warning.o emalloc.o
- X
- X# RANLIB is ranlib on non-USG systems, echo on USG systems
- XRANLIB=ranlib
- X#RANLIB=echo
- X
- Xu: $(OBJS)
- X ar ruv ../libcnews.a $(OBJS)
- X
- Xall: $(OBJS)
- X
- Xlibc.a: $(SRCS)
- X $(CC) $(CFLAGS) -c $?
- X ar ru $@ *.o
- X rm *.o
- X $(RANLIB) $@
- Xlint:
- X lint $(LINTFLAGS) $(SRCS)
- X
- Xclean:
- X rm -f *.o *.a getdate.c y.*.h y.*.c
- !
- echo 'libc/emalloc.c':
- sed 's/^X//' >'libc/emalloc.c' <<'!'
- X/*
- X * emalloc - malloc with error() called when out of space
- X */
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include "libc.h"
- X
- Xextern void error();
- X
- Xchar *
- Xemalloc(amount)
- Xunsigned amount;
- X{
- X register char *it;
- X char camount[25]; /* Enough to sprintf an unsigned. */
- X
- X it = malloc(amount);
- X if (it == NULL) {
- X sprintf(camount, "%u", amount);
- X error("malloc(%s) failed", camount);
- X }
- X
- X return(it);
- X}
- !
- echo 'libc/fgetmfs.3':
- sed 's/^X//' >'libc/fgetmfs.3' <<'!'
- X.TH FGETMFS 3 local
- X.DA 23 May 1989
- X.SH NAME
- Xfgetmfs \- read an arbitrarily long, possibly continued line
- X.SH SYNOPSIS
- X.B "#include <stdio.h>
- X.br
- X.B "#include <fgetmfs.h>
- X.PP
- X.B "char *fgetmfs(stream, limit, cont)"
- X.br
- X.B "FILE *stream;"
- X.br
- X.B "int limit, cont;"
- X.PP
- X.B "char *fgetms(stream)
- X.br
- X.B "FILE *stream;"
- X.PP
- X.B "char *cfgetms(stream)
- X.br
- X.B "FILE *stream;"
- X.SH DESCRIPTION
- X.I Fgetmfs
- Xreads an arbitrarily long line from
- X.IR stream ,
- Xallocating memory via
- X.IR malloc (3)
- Xas needed.
- XIf
- X.I limit
- Xis non-negative,
- X.I fgetmfs
- Xwill read no more than
- X.I limit
- Xbytes from
- X.IR stream .
- XFor efficiency,
- Xif
- X.I cont
- Xis not
- X.IR CONT_NO ,
- Xsuch as
- X.I CONT_NOSPC
- Xor
- X.IR CONT_SPC ,
- Xoccurrences of a backslash and a newline together
- Xand in that order
- Xwill be deleted from the input stream;
- Xif
- X.I cont
- Xis
- X.IR CONT_NOSPC ,
- Xany whitespace after the newline
- Xin the input stream will also be deleted from it.
- X.PP
- XThe macros
- X.I fgetms
- X(to read without continuations)
- Xand
- X.I cfgetms
- X(to read with continuations and remove leading whitespace)
- Xshould be used instead when the
- X.I limit
- Xis not needed.
- X.PP
- X.I Fgetmfs
- Xis intended to provide a reliable mechanism for reading
- Xinput containing lines of arbitrary length,
- Xrather than trusting that no line with be longer than some
- Xarbitrary tolerance.
- X.PP
- XThe memory returned by
- X.I fgetmfs
- Xshould be returned when no longer needed via
- X.IR free (3).
- X.\" .SH FILES
- X.SH SEE ALSO
- X.IR malloc (3),
- X.IR fgets (3)
- X.SH DIAGNOSTICS
- XReturns NULL (0) if memory cannot be allocated or upon reading end-of-file;
- Xuse
- X.I feof(stream)
- Xto distinguish.
- X.SH HISTORY
- XWritten by Geoff Collyer
- Xat the University of Toronto
- Xas part of the C news project.
- X.SH BUGS
- XIt's too slow.
- X.br
- XThe meaning of the
- X.I cont
- Xflag is ugly,
- Xbut layering this form of continuation on top is even slower.
- !
- echo 'libc/fgetmfs.c':
- sed 's/^X//' >'libc/fgetmfs.c' <<'!'
- X/*
- X * fgetmfs - read an arbitrarily long, possibly continued line;
- X * return a pointer to it, in malloced memory.
- X */
- X
- X#include <stdio.h>
- X#include <ctype.h>
- X#include <sys/types.h>
- X#include <fgetmfs.h>
- X#include "libc.h"
- X
- X#define max(a,b) ((a) > (b)? (a): (b))
- X#define min(a,b) ((a) < (b)? (a): (b))
- X
- X/* One could make these arguments, with defaults. */
- X#define INITLN 90 /* initial allocation per line */
- X#define GROWLN 200 /* additional allocation size */
- X
- X/* getseg returns */
- X#define FAILED 0
- X#define HITLIMIT 1
- X#define OKAY 2
- X
- Xstatic unsigned sz; /* bytes currently allocated (in line) */
- Xstatic int incr; /* for sz */
- Xstatic char *line; /* current allocation */
- Xstatic char *segment; /* start of line segment in "line" */
- Xstatic char *morep; /* last byte possibly containing input */
- X
- X/*
- X * `fget malloced, flagged string' with continuations and limit on bytes.
- X * The limit is like fgets's; limit-1 bytes can be read. -1 means "no limit".
- X */
- Xchar *
- Xfgetmfs(fp, limit, cont)
- XFILE *fp;
- Xregister int limit, cont; /* honour \ continuations? */
- X{
- X /* allocate room for an initial segment of a line */
- X sz = INITLN;
- X incr = GROWLN;
- X if (limit >= 0 && sz > limit)
- X sz = limit;
- X line = malloc(sz);
- X if (line == NULL)
- X return NULL; /* no memory, can't go on */
- X segment = line;
- X morep = line + sz - 2;
- X
- X /* read all lines, including continuations */
- X do {
- X /* read the first segment of a line */
- X *morep = '\0'; /* mark end of segment */
- X if (fgets(segment, (int)sz-(segment-line), fp) == NULL) {
- X free(line); /* EOF: give up */
- X return NULL;
- X }
- X
- X /* read more of this line, if it didn't fit */
- X while (*morep != '\0' && *morep != '\n') {
- X register int code = getseg(fp, limit);
- X
- X if (code == FAILED)
- X return NULL;
- X else if (code == HITLIMIT)
- X break;
- X }
- X } while (cont && ismore(fp, cont));
- X return realloc(line, (unsigned)(strlen(line)+1)); /* save space */
- X}
- X
- Xstatic int
- Xgetseg(fp, limit)
- XFILE *fp;
- Xregister int limit;
- X{
- X register int oldsz = sz;
- X
- X /* extend the allocation, within limit */
- X incr = GROWLN;
- X sz += incr;
- X if (limit >= 0 && sz > limit) {
- X sz = limit;
- X incr = sz - oldsz;
- X }
- X if (incr <= 0) /* hit the limit? */
- X return HITLIMIT;
- X line = realloc(line, sz);
- X if (line == NULL)
- X return FAILED; /* no memory, can't go on */
- X /* -1 starts on the terminating NUL of the prev. segment */
- X segment = line + oldsz - 1;
- X morep = line + sz - 2; /* recompute for new line, sz */
- X
- X /* read the next segment */
- X *morep = '\0';
- X /* +1 because segment includes terminating NUL of the prev. segment */
- X if (fgets(segment, incr+1, fp) == NULL) {
- X free(line); /* EOF: give up */
- X return FAILED;
- X }
- X return OKAY;
- X}
- X
- Xstatic int
- Xismore(fp, cont)
- Xregister FILE *fp;
- Xint cont;
- X{
- X register char *nlp;
- X
- X /* got a whole line: is it to be continued? */
- X if (incr > 0 && cont && (nlp = rindex(line, '\n')) != NULL &&
- X nlp > line && *--nlp == '\\') {
- X *nlp = '\0'; /* delete "\\\n" */
- X segment = nlp;
- X if (cont == CONT_NOSPC) {
- X register int c;
- X
- X /* discard leading whitespace */
- X while ((c = getc(fp)) != EOF && c != '\n' &&
- X isascii(c) && isspace(c))
- X ;
- X if (c != EOF)
- X (void) ungetc(c, fp);
- X }
- X return 1; /* read next line */
- X } else
- X return 0;
- X}
- !
- echo 'libc/standard.c':
- sed 's/^X//' >'libc/standard.c' <<'!'
- X#define NULL 0
- X
- Xextern void closeall();
- Xextern char **environ;
- X
- Xstatic char *stdenv[] = {
- X/* =()< "PATH=@<NEWSPATH>@",>()= */
- X "PATH=/bin:/usr/bin",
- X "IFS= \t\n",
- X NULL
- X};
- X
- Xvoid
- Xstandard()
- X{
- X environ = stdenv;
- X closeall(1);
- X}
- X
- Xvoid
- Xsafe()
- X{
- X setgid(getgid());
- X setuid(getuid());
- X closeall(1);
- X}
- !
- echo 'libc/stdfdopen.c':
- sed 's/^X//' >'libc/stdfdopen.c' <<'!'
- X/*
- X * stdfdopen - ensure that the standard i/o descriptors are open,
- X * to avoid mayhem.
- X */
- X
- X#include <stdio.h>
- X#include <errno.h>
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X
- X#ifndef NSYSFILE
- X#define NSYSFILE 3 /* hmm, not on V8 */
- X#endif
- X
- Xextern int errno;
- X
- Xvoid
- Xstdfdopen() /* ensure standard descriptors are open */
- X{
- X register int fd;
- X struct stat stbuf;
- X
- X for (fd = 0; fd < NSYSFILE; fd++)
- X if (fstat(fd, &stbuf) < 0 && errno == EBADF)
- X if (open("/dev/null", 2) != fd) /* open read/write */
- X exit(1); /* bad news */
- X}
- !
- echo 'libc/error.3':
- sed 's/^X//' >'libc/error.3' <<'!'
- X.TH ERROR 3 local
- X.DA 8 May 1984
- X.SH NAME
- Xerror, warning \- print error messages
- X.SH SYNOPSIS
- X.nf
- X.B error(s1, s2)
- X.B char *s1;
- X.B char *s2;
- X
- X.B warning(s1, s2)
- X.B char *s1;
- X.B char *s2;
- X
- X.B extern char *progname;
- X.B extern int errno;
- X
- X.B progname = argv[0];
- X.SH DESCRIPTION
- X.I Warning
- Xprints an error message, with suitable embellishments,
- Xand clears
- X.IR errno .
- X.I Error
- Xdoes likewise and then exits.
- XThe
- X.I s1
- Xargument should be a
- X.I printf
- Xformat string (without a trailing newline), with
- X.I s2
- Xavailable as an argument.
- X.PP
- XIf there is an environment variable
- X.BR CMDNAME
- Xwith non-null value,
- Xits contents are printed first, followed by a colon.
- XFollowing this,
- Xany non-null value of
- X.I progname
- Xis printed, followed by a colon and a space.
- XFollowing this,
- X.IR fprintf (3)
- Xis invoked with
- X.I s1
- Xas the format string and
- X.I s2
- Xas the argument.
- XIf the value of
- X.I errno
- Xis within the normal range,
- Xa standard elaborating message is printed (see
- X.IR intro (2)).
- X.PP
- X.B CMDNAME
- Xshould be set by shellfiles that expect subordinate programs to
- Xissue error message in the shellfile's name.
- X.I Progname
- Xshould be set by all programs;
- X.I argv[0]
- Xis usually a suitable thing to set it to.
- X.I Errno
- Xis set by system calls and various other routines,
- Xalthough its use is not universal;
- Xnote that it is not reset by successful system calls following an
- Xunsuccessful one.
- X.SH SEE ALSO
- Xintro(2), intro(3), printf(3), exit(2), getopt(3)
- X.SH DIAGNOSTICS
- X.IR Error 's
- Xexit status is 1.
- X.SH HISTORY
- XLocal products, modelled on the
- X.I error
- Xin Kernighan&Pike.
- X.SH BUGS
- XBe nice if they could take a full
- X.IR printf -style
- Xargument list.
- !
- echo 'libc/error.c':
- sed 's/^X//' >'libc/error.c' <<'!'
- X/*
- X * error - print best error message possible and exit
- X */
- X
- X#include <stdio.h>
- X
- Xextern void warning();
- X
- Xvoid
- Xerror(s1, s2)
- Xchar *s1;
- Xchar *s2;
- X{
- X warning(s1, s2);
- X exit(1);
- X}
- !
- echo 'libc/warning.c':
- sed 's/^X//' >'libc/warning.c' <<'!'
- X/*
- X * warning - print best error message possible and clear errno
- X */
- X
- X#include <stdio.h>
- X
- Xvoid
- Xwarning(s1, s2)
- Xchar *s1;
- Xchar *s2;
- X{
- X char *cmdname;
- X extern int errno, sys_nerr;
- X extern char *sys_errlist[];
- X extern char *progname;
- X extern char *getenv();
- X
- X (void) fflush(stdout); /* hack */
- X cmdname = getenv("CMDNAME");
- X if (cmdname != NULL && *cmdname != '\0')
- X fprintf(stderr, "%s:", cmdname); /* No space after :. */
- X if (progname != NULL)
- X fprintf(stderr, "%s: ", progname);
- X fprintf(stderr, s1, s2);
- X if (errno > 0 && errno < sys_nerr)
- X fprintf(stderr, " (%s)", sys_errlist[errno]);
- X fprintf(stderr, "\n");
- X errno = 0;
- X}
- !
- echo 'libc/standard.3':
- sed 's/^X//' >'libc/standard.3' <<'!'
- X.TH STANDARD 3 local
- X.DA 9 Feb 1982
- X.SH NAME
- Xstandard, safe \- standardize conditions in preparation for exec
- X.SH SYNOPSIS
- X.B standard()
- X.PP
- X.B safe()
- X.SH DESCRIPTION
- X.I Standard
- Xalters a process's environment to make it relatively safe to do
- X.IR execvp ,
- X.IR system ,
- X.IR popen ,
- Xetc.
- XIt closes all descriptors except
- Xthe standard ones and supplies a standard set of environment variables
- Xthat ensure a standard interpretation of shell commands and a
- Xstandard search path for programs.
- X.PP
- X.I Safe
- Xis similar, but is intended for use in shell escapes and suchlike.
- XIt leaves the environment variables untouched but turns off
- Xsetuid and setgid permissions.
- X.PP
- XUse of either one permits a setuid/setgid program to
- Xrun other programs without inadvertently bestowing special powers
- Xon nonstandard programs.
- XCare must still be exercised as to what the standard descriptors
- Xrefer to,
- Xand it is still possible for
- Xprograms executed after use of
- X.I standard
- X(as opposed to
- X.IR safe )
- Xto give away special powers through
- X.I their
- Xcarelessness.
- X.SH SEE ALSO
- Xenviron(3), closeall(3)
- X.SH HISTORY
- XLocal products.
- X.SH BUGS
- X.I Standard
- Xmust necessarily supply standard values for some environment variables,
- Xbut it is not clear whether it should pass other variables
- Xthrough or eliminate them.
- XThe current implementation eliminates them, which is safer but sometimes
- Xinconvenient.
- X.PP
- XOne can construct elaborate scenarios in which a setuid
- Xprogram employing
- X.I safe
- Xcould be duped into
- Xexecuting a user-supplied program in a current directory
- Xthe user ordinarily could not have reached.
- X.PP
- XPossibly
- Xone or both should standardize the
- X.I umask
- Xsetting.
- !
- echo 'libc/closeall.3':
- sed 's/^X//' >'libc/closeall.3' <<'!'
- X.TH CLOSEALL 3 local
- X.DA 9 Feb 1982
- X.SH NAME
- Xcloseall \- close all files
- X.SH SYNOPSIS
- X.ft B
- Xcloseall(leavestd)
- X.br
- Xint leavestd;
- X.ft R
- X.SH DESCRIPTION
- X.I Closeall
- Xcloses all currently-open file descriptors.
- XIf
- X.I leavestd
- Xis non-zero,
- Xthe standard input, output, and diagnostic descriptors are left open;
- Xotherwise they are closed too.
- X.SH SEE ALSO
- Xclose(2), standard(3)
- X.SH HISTORY
- XLocal invention.
- X.SH BUGS
- XNothing wrong with
- X.IR closeall ,
- Xbut there ought to be an
- X.IR fcloseall .
- !
- echo 'libc/closeall.c':
- sed 's/^X//' >'libc/closeall.c' <<'!'
- X#include <sys/param.h>
- X
- Xvoid
- Xcloseall(leavestd)
- Xint leavestd;
- X{
- X register int i;
- X
- X for (i = (leavestd? 3: 0); i < NOFILE; i++)
- X close(i);
- X}
- !
- echo 'libc/README':
- sed 's/^X//' >'libc/README' <<'!'
- XThese should, ideally, be inserted into your C library if they aren't
- Xthere already. If they can't be put into your C library nor -llocal,
- Xjust put the ones not in your C library into libc.a in this directory.
- X
- XThey were all written by either Henry Spencer, Geoff Collyer or Brian
- XKernighan & Rob Pike.
- !
- echo 'libc/efopen.3':
- sed 's/^X//' >'libc/efopen.3' <<'!'
- X.TH EFOPEN 3 local
- X.DA 24 April 1984
- X.SH NAME
- Xefopen \- open a stream, checking for errors
- X.SH SYNOPSIS
- X.nf
- X.B FILE *
- X.B efopen(file, mode)
- X.B char *file;
- X.B char *mode;
- X.SH DESCRIPTION
- X.I Efopen
- Xinvokes
- X.IR fopen (3)
- Xand checks the result for errors.
- XIn the absence of errors, it returns the stream pointer;
- Xin the presence of errors, it prints a message and exits.
- X.SH SEE ALSO
- Xfopen(3), error(3)
- X.SH DIAGNOSTICS
- XExit status, in the event of error, is 1.
- X.SH HISTORY
- XLocal product, roughly following the one in Kernighan&Pike.
- !
- echo 'libc/efopen.c':
- sed 's/^X//' >'libc/efopen.c' <<'!'
- X/*
- X * efopen - fopen file, exit with message if impossible
- X */
- X
- X#include <stdio.h>
- X
- X/* imports from libc */
- Xextern char *strcpy(), *strncat();
- Xextern void error();
- X
- Xstatic char message[] = "can't open file \"%s\" mode ";
- X
- XFILE *
- Xefopen(file, mode)
- Xchar *file;
- Xchar *mode;
- X{
- X FILE *fp;
- X char fullmsg[sizeof(message)+10];
- X extern int errno;
- X
- X errno = 0; /* Wipe out residue of earlier errors. */
- X fp = fopen(file, mode);
- X if (fp == NULL) {
- X (void) strcpy(fullmsg, message);
- X (void) strncat(fullmsg, mode, 10);
- X error(fullmsg, file);
- X /* NOTREACHED */
- X }
- X return(fp);
- X}
- !
- echo done
-
-
-